package falcon.script;

import java.util.ArrayList;

import falcon.common.Errno;
import falcon.script.FalconLangLoader.ProcInstruction;
import falcon.script.FalconLangLoader.ProcLine;
import falcon.script.FalconLangLoader.Procedure;

public final class FalconLangDebuger {

	public FalconLangDebuger(FalconLangGlobal global) {
		m_global = global;
	}

	public int printAssembly(String path, StringBuilder sb) {
		FalconLangLoader loader = m_global.getLoader();
		Procedure procedure = loader.load(path);
		int errno = procedure.errno;
		if (errno != Errno.SUCCESS) {
			return errno;
		}
		ProcLine[] pLines = procedure.lines;
		ProcInstruction[] pInstructions = procedure.list;
		for (int x = 0; x < pLines.length; x ++) {
			ProcLine pLine = pLines[x];
			String line = pLine.line;
			if ("".equals(line)) {
				continue;
			}
			String text = String.format("# line:%d\n# %s\n", x + 1, line);
			sb.append(text);
			int y = pLine.offset;
			int z = pLine.offset + pLine.count;
			while (y < z) {
				FalconLangInstruction instruction = pInstructions[y].instruction;
				text = String.format("%s\n", instruction.toString());
				sb.append(text);
				y ++;
			}
			sb.append('\n');
		}
		return Errno.SUCCESS;
	}
	
	public int printAbstractSyntaxTree(FalconLangAst ast, StringBuilder sb) {
		ArrayList<Line> list = new ArrayList<Line>(256);
		printTreeNode(1, ast, list);
		return Errno.SUCCESS;
	}
	
	private int printTreeNode(int layer, FalconLangAst ast, ArrayList<Line> list) {
		if (ast == null) {
			return 0;
		}
		if (list.size() < layer * 4) {
			for (int i = 0; i < 4; i ++) {
				Line line = new Line();
				line.x = 0;
				line.sb = new StringBuilder(128);
				list.add(line);
			}
		}
		int left = printTreeNode(layer + 1, ast.child1, list);
		int right = printTreeNode(layer + 1, ast.child2, list);
		String title = ast.toString();
		if (title.length() > 15) {
			title = title.substring(0, 12) + "...";
		}
		Line line0 = list.get(layer * 4 - 4);
		line0.sb.append("    ");
		line0.sb.append(title);
		line0.x += 4 + title.length();
		int center = line0.x - 1 - title.length() / 2;
		if (left < 0 && right < 0) {
			return center;
		}
		Line line1 = list.get(layer * 4 - 3);
		Line line2 = list.get(layer * 4 - 2);
		if (left >= 0) {
			
		}
		if (right >= 0) {
			
		}
		
		Line line3 = list.get(layer * 4 - 1);
		if (left >= 0 && right >= 0) {
			while (line1.x < center - 1) {
				line1.sb.append(' ');
				line1.x ++;
			}
			line1.sb.append('|');
			line1.x = center;
			while (line2.x < left) {
				line2.sb.append(' ');
				line2.x ++;
			}
			line2.sb.append('+');
			line2.x ++;
			while (line2.x < right) {
				line2.sb.append('-');
				line2.x ++;
			}
			line2.sb.append('+');
		}
		
		return 0;
	}
	
	private static final class Line {
		public int x;
		public StringBuilder sb;
	}
	
	private FalconLangGlobal m_global;
}
